#include "database/DatabaseManager.h"
#include <QSqlQuery>
#include <QSqlError>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDateTime>
#include <QDir>
#include <QStandardPaths>
#include <QDebug>

DatabaseManager::DatabaseManager()
{
}

DatabaseManager::~DatabaseManager()
{
    close();
}

DatabaseManager& DatabaseManager::instance()
{
    static DatabaseManager instance;
    return instance;
}

bool DatabaseManager::initialize(const QString &dbPath)
{
    if (m_database.isOpen()) {
        return true;
    }
    
    // 设置数据库路径
    if (dbPath.isEmpty()) {
        QString dataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
        QDir().mkpath(dataPath);
        m_dbPath = dataPath + "/obfuscator.db";
    } else {
        m_dbPath = dbPath;
    }
    
    // 创建数据库连接
    m_database = QSqlDatabase::addDatabase("QSQLITE");
    m_database.setDatabaseName(m_dbPath);
    
    if (!m_database.open()) {
        emit databaseError("Failed to open database: " + m_database.lastError().text());
        return false;
    }
    
    // 创建表
    if (!createTables()) {
        emit databaseError("Failed to create tables");
        return false;
    }
    
    return true;
}

void DatabaseManager::close()
{
    if (m_database.isOpen()) {
        m_database.close();
    }
}

bool DatabaseManager::createTables()
{
    QSqlQuery query;
    
    // 创建混淆记录表
    QString createRecordsTable = R"(
        CREATE TABLE IF NOT EXISTS obfuscation_records (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            version_id TEXT UNIQUE NOT NULL,
            project_path TEXT NOT NULL,
            timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
            config TEXT,
            statistics TEXT,
            status TEXT,
            notes TEXT
        )
    )";
    
    if (!query.exec(createRecordsTable)) {
        qWarning() << "Failed to create records table:" << query.lastError().text();
        return false;
    }
    
    // 创建映射关系表
    QString createMappingsTable = R"(
        CREATE TABLE IF NOT EXISTS mappings (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            version_id TEXT NOT NULL,
            original_name TEXT NOT NULL,
            obfuscated_name TEXT NOT NULL,
            type TEXT,
            file_path TEXT,
            FOREIGN KEY(version_id) REFERENCES obfuscation_records(version_id)
        )
    )";
    
    if (!query.exec(createMappingsTable)) {
        qWarning() << "Failed to create mappings table:" << query.lastError().text();
        return false;
    }
    
    // 创建索引
    query.exec("CREATE INDEX IF NOT EXISTS idx_version_id ON mappings(version_id)");
    query.exec("CREATE INDEX IF NOT EXISTS idx_original_name ON mappings(original_name)");
    
    return true;
}

bool DatabaseManager::saveObfuscationRecord(const QJsonObject &record)
{
    QSqlQuery query;
    query.prepare(R"(
        INSERT INTO obfuscation_records 
        (version_id, project_path, config, statistics, status, notes)
        VALUES (:version_id, :project_path, :config, :statistics, :status, :notes)
    )");
    
    query.bindValue(":version_id", record["version_id"].toString());
    query.bindValue(":project_path", record["project_path"].toString());
    query.bindValue(":config", QJsonDocument(record["config"].toObject()).toJson());
    query.bindValue(":statistics", QJsonDocument(record["statistics"].toObject()).toJson());
    query.bindValue(":status", record["status"].toString());
    query.bindValue(":notes", record["notes"].toString());
    
    if (!query.exec()) {
        emit databaseError("Failed to save record: " + query.lastError().text());
        return false;
    }
    
    return true;
}

QJsonArray DatabaseManager::getObfuscationHistory(int limit)
{
    QJsonArray history;
    
    QSqlQuery query;
    query.prepare("SELECT * FROM obfuscation_records ORDER BY timestamp DESC LIMIT :limit");
    query.bindValue(":limit", limit);
    
    if (!query.exec()) {
        emit databaseError("Failed to get history: " + query.lastError().text());
        return history;
    }
    
    while (query.next()) {
        QJsonObject record;
        record["id"] = query.value("id").toInt();
        record["version_id"] = query.value("version_id").toString();
        record["project_path"] = query.value("project_path").toString();
        record["timestamp"] = query.value("timestamp").toString();
        record["config"] = QJsonDocument::fromJson(query.value("config").toByteArray()).object();
        record["statistics"] = QJsonDocument::fromJson(query.value("statistics").toByteArray()).object();
        record["status"] = query.value("status").toString();
        record["notes"] = query.value("notes").toString();
        
        history.append(record);
    }
    
    return history;
}

QJsonObject DatabaseManager::getRecordByVersion(const QString &versionId)
{
    QJsonObject record;
    
    QSqlQuery query;
    query.prepare("SELECT * FROM obfuscation_records WHERE version_id = :version_id");
    query.bindValue(":version_id", versionId);
    
    if (!query.exec() || !query.next()) {
        return record;
    }
    
    record["id"] = query.value("id").toInt();
    record["version_id"] = query.value("version_id").toString();
    record["project_path"] = query.value("project_path").toString();
    record["timestamp"] = query.value("timestamp").toString();
    record["config"] = QJsonDocument::fromJson(query.value("config").toByteArray()).object();
    record["statistics"] = QJsonDocument::fromJson(query.value("statistics").toByteArray()).object();
    record["status"] = query.value("status").toString();
    record["notes"] = query.value("notes").toString();
    
    return record;
}

bool DatabaseManager::deleteRecord(const QString &versionId)
{
    QSqlQuery query;
    
    // 开始事务
    m_database.transaction();
    
    // 删除映射关系
    query.prepare("DELETE FROM mappings WHERE version_id = :version_id");
    query.bindValue(":version_id", versionId);
    if (!query.exec()) {
        m_database.rollback();
        return false;
    }
    
    // 删除记录
    query.prepare("DELETE FROM obfuscation_records WHERE version_id = :version_id");
    query.bindValue(":version_id", versionId);
    if (!query.exec()) {
        m_database.rollback();
        return false;
    }
    
    // 提交事务
    return m_database.commit();
}

bool DatabaseManager::clearObfuscationHistory()
{
    QSqlQuery query;
    // 删除所有 obfuscation_records 及相关 mappings
    if (!query.exec("DELETE FROM mappings")) {
        emit databaseError("Failed to clear mappings: " + query.lastError().text());
        return false;
    }
    if (!query.exec("DELETE FROM obfuscation_records")) {
        emit databaseError("Failed to clear records: " + query.lastError().text());
        return false;
    }
    return true;
}

bool DatabaseManager::saveMappings(const QString &versionId, const QJsonObject &mappings)
{
    QSqlQuery query;
    
    // 开始事务
    m_database.transaction();
    
    // 遍历映射关系
    for (auto it = mappings.begin(); it != mappings.end(); ++it) {
        query.prepare(R"(
            INSERT INTO mappings 
            (version_id, original_name, obfuscated_name, type)
            VALUES (:version_id, :original, :obfuscated, :type)
        )");
        
        query.bindValue(":version_id", versionId);
        query.bindValue(":original", it.key());
        query.bindValue(":obfuscated", it.value().toString());
        query.bindValue(":type", "class"); // 这里可以根据实际情况设置类型
        
        if (!query.exec()) {
            m_database.rollback();
            emit databaseError("Failed to save mappings: " + query.lastError().text());
            return false;
        }
    }
    
    return m_database.commit();
}

QJsonObject DatabaseManager::getMappings(const QString &versionId)
{
    QJsonObject mappings;
    
    QSqlQuery query;
    query.prepare("SELECT original_name, obfuscated_name FROM mappings WHERE version_id = :version_id");
    query.bindValue(":version_id", versionId);
    
    if (!query.exec()) {
        emit databaseError("Failed to get mappings: " + query.lastError().text());
        return mappings;
    }
    
    while (query.next()) {
        QString original = query.value("original_name").toString();
        QString obfuscated = query.value("obfuscated_name").toString();
        mappings[original] = obfuscated;
    }
    
    return mappings;
}

bool DatabaseManager::cleanOldRecords(int daysToKeep)
{
    QSqlQuery query;
    QDateTime cutoffDate = QDateTime::currentDateTime().addDays(-daysToKeep);
    
    query.prepare("DELETE FROM obfuscation_records WHERE timestamp < :cutoff");
    query.bindValue(":cutoff", cutoffDate.toString(Qt::ISODate));
    
    return query.exec();
}